package com.atguigu.crowd.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.atguigu.crowd.constant.CrowdConstant;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;


public class CrowdUtil {


    /***
     * 专门负责上传文件到 OSS 服务器的工具方法
     *  @param endpoint OSS 参数
     *  @param accessKeyId OSS 参数
     *  @param accessKeySecret OSS 参数
     *  @param bucketName OSS 参数
     *  @param bucketDomain OSS 参数
     *  @param inputStream 要上传的文件的输入流
     *  @param originalName 要上传的文件的原始文件名
     *  @return 包含上传结果以及上传的文件在 OSS 上的访问路径
     *  */
    public static ResultEntity<String> uploadFileToOss(String endpoint, String accessKeyId, String accessKeySecret,String bucketName, String bucketDomain, InputStream inputStream, String originalName) {
        // 创建 OSSClient 实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 生成上传文件的目录
        String folderName = new SimpleDateFormat("yyyy-MM-dd").format(new Date());

        // 生成上传文件在 OSS 服务器上保存时的文件名
        // 原始文件名：beautfulgirl.jpg
        // 生成文件名：wer234234efwer235346457dfswet346235.jpg
        // 使用 UUID 生成文件主体名称
        String fileMainName = UUID.randomUUID().toString().replace("-", "");
        // 从原始文件名中获取文件扩展名
        String extensionName = originalName.substring(originalName.lastIndexOf("."));
        // 使用目录、文件主体名称、文件扩展名称拼接得到对象名称
        String objectName = folderName + "/" + fileMainName + extensionName;

        try {
            // 调用 OSS 客户端对象的方法上传文件并获取响应结果数据
            PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, inputStream);
            // 从响应结果中获取具体响应消息
            ResponseMessage responseMessage = putObjectResult.getResponse();
            // 根据响应状态码判断请求是否成功
            if (responseMessage == null) {
                // 拼接访问刚刚上传的文件的路径
                String ossFileAccessPath = bucketDomain + "/" + objectName;
                // 当前方法返回成功
                return ResultEntity.successWithData(ossFileAccessPath);
            } else {
                // 获取响应状态码
                int statusCode = responseMessage.getStatusCode();
                // 如果请求没有成功，获取错误消息
                String errorMessage = responseMessage.getErrorResponseAsString();
                // 当前方法返回失败
                return ResultEntity.failed(" 当 前 响 应 状 态 码 =" + statusCode + " 错 误 消 息 =" + errorMessage);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 当前方法返回失败
            return ResultEntity.failed(e.getMessage());
        } finally {
            if (ossClient != null) {
                // 关闭 OSSClient。
                ossClient.shutdown();
            }
        }
    }





    /**
     * //
     * //        <dependency>
     * //            <groupId>com.aliyun</groupId>
     * //            <artifactId>aliyun-java-sdk-core</artifactId>
     * //            <version>4.5.16</version>
     * //        </dependency>
     * <p>
     * 阿里云发送短信
     *
     * @param phoneNum
     * @param accesskey
     * @param secret
     * @param signName
     * @param TemplateCode
     * @return
     */
    public static ResultEntity<String> sendCodeByShortMessage(
            String phoneNum,
            String accesskey,
            String secret,
            String signName,
            String TemplateCode) {

        //连接阿里云服务器
        DefaultProfile profile = DefaultProfile.getProfile("cn-qingdao", accesskey, secret);
        IAcsClient client = new DefaultAcsClient(profile);

        //构建请求
        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com"); //此处禁止修改
        request.setSysVersion("2017-05-25"); //此处禁止修改
        request.setSysAction("SendSms");

        //自定义的参数（手机号，验证码，签名，模版）
        request.putQueryParameter("PhoneNumbers", phoneNum);
        request.putQueryParameter("SignName", signName);
        request.putQueryParameter("TemplateCode", TemplateCode);

        //生成验证码
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            int random = (int) (Math.random() * 10);
            builder.append(random);
        }
        String code = builder.toString();
        HashMap<String, Object> map = new HashMap<>();
        map.put("code", code);

        request.putQueryParameter("TemplateParam", JsonUtils.toJsonString(map));

        try {
            CommonResponse response = client.getCommonResponse(request);
            String data = response.getData();

            HashMap parse = JsonUtils.parse(data, HashMap.class);
            Object code1 = parse.get("Code");
            Object message = parse.get("Message");
            if ("OK".equals(code1) && "OK".equals(message)) {
                //操作成功，把生成的验证码返回
                return ResultEntity.successWithData(code);
            }

            return ResultEntity.failed(message.toString());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultEntity.failed(e.getMessage());
        }

    }


    /**
     * 判断是否是ajax请求
     *
     * @param request
     * @return
     */
    public static boolean judgeRequestType(HttpServletRequest request) {

        //1、获取请求消息头
        String acceptHeader = request.getHeader("Accept");
        String xRequestHeader = request.getHeader("X-Requested-With");

        //2、判断
        return (acceptHeader != null && acceptHeader.contains("application/json"))
                || ("X-Requested-With".equals(xRequestHeader));

    }


    /**
     * 此方法是用于给字符串进行md5加密的工具方法
     *
     * @param source 传入要加密的内容
     * @return 进行md5加密后的结果
     */
    public static String md5(String source) {

        //1、判断source是否有效
        if (source == null || source.length() == 0) {
            //2、如果不是有效的字符串抛出异常
            throw new RuntimeException(CrowdConstant.MESSAGE_STRING_INVALIDATE);
        }

        try {
            // 3、获取MessageDigest对象 jdk提供的
            //表示算法名
            String algorithm = "md5";
            //得到MessageDigest对象，设置加密方式为md5
            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);

            // 4、将获得的明文字符串转换为字节数组
            byte[] input = source.getBytes();

            // 5、对转换得到的字节数组进行md5加密
            byte[] output = messageDigest.digest(input);

            // 6、创建BigInteger对象
            //signum : -1表示负数、0表示零、1表示正数
            int signum = 1;
            //将字节数组转换成BigInteger
            BigInteger bigInteger = new BigInteger(signum, output);

            // 7、设置将bigInteger的值按照16进制转换成字符串，最后全部转换成大写，得到最后的加密结果
            int radix = 16;
            String encoded = bigInteger.toString(radix).toUpperCase();

            //返回加密后的字符串
            return encoded;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        //触发异常则返回null
        return null;
    }
}
